package com.meilai.project.service.system.testFlow.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.dto.system.TestFlowDTO;
import com.meilai.project.dto.workflow.FlowBusinessDataSuperEntity;
import com.meilai.project.dto.workflow.WorkFlowCheckDTO;
import com.meilai.project.entity.system.TestFlow;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.system.TestFlowMapper;
import com.meilai.project.service.system.testFlow.TestFlowService;
import com.meilai.project.service.workflow.WFDataService;
import com.meilai.project.util.ThreadLocalUserUtil;
import com.meilai.project.util.WorkFlowUtil;
import com.meilai.project.vo.system.TestFlowVO;
import org.apache.commons.lang3.BooleanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;

/**
 * @author 张驰
 * @date 2020/12/1 10:02
 */
@Service
public class TestFlowServiceImpl extends ServiceImpl<TestFlowMapper,TestFlow> implements TestFlowService {
    private final static Logger logger = LoggerFactory.getLogger(TestFlowServiceImpl.class);

    @Autowired
    private WFDataService wfDataService;

    @Override
    public Page<TestFlowVO> selectPageList(Integer current_page, Integer page_size) {
        Page<TestFlowVO> page = new Page<TestFlowVO>(current_page,page_size);
        List<TestFlowVO> list = baseMapper.selectPageList(page);
        // 当前人
        Long userId = ThreadLocalUserUtil.get().getId();
        // 设置是否需要审批
        try{
            HashMap<Long,Boolean> canCheckMap = WorkFlowUtil.canCheckData(userId,list,TestFlow.class);
            for(TestFlowVO vo : list){
                vo.setCanCheck(BooleanUtils.isTrue(canCheckMap.get(vo.getId())));
            }
        }catch (Exception E){
            logger.error("需审核设置失败");
        }
        return page.setRecords(list);
    }

    @Override
    @Transactional
    public boolean addOne(TestFlowDTO dto){
        // 业务数据字段
        TestFlow temp = new TestFlow();
        BeanUtils.copyProperties(dto, temp);
        // 当前人
        Long userId = ThreadLocalUserUtil.get().getId();
        // 设置流程字段，flow_type请自行对应dict_flow_type表中的id
        FlowBusinessDataSuperEntity fbdse = WorkFlowUtil.getStartSuperDataEntity(userId,dto.getDepartmentId(),1,dto.getName());
        BeanUtils.copyProperties(fbdse, temp);
        // 插入业务表
        boolean flag = save(temp);
        if(!flag) throw new CommonException("新增数据失败");
        // 开始流程
        int flowResult = new WorkFlowUtil<TestFlow,TestFlowMapper>(temp.getId(),userId,TestFlow.class)
                .Begin(0L,"", new TestFlow());

        if(flowResult == 1){
            // 开始流程成功，审核后仍处于流程中
            return true;
        }else if(flowResult == 2){
            // 流程通过
            // todo 审核通过后的业务
            return true;
        }else{
            throw new CommonException("开始审核流程失败");
        }
    }

    @Override
    @Transactional
    public boolean editOne(TestFlowDTO dto){
        if (dto.getId() == null) throw new CommonException("id不存在");
        TestFlow temp = getById(dto.getId());
        if (temp == null) throw new CommonException("数据不存在");
        // 业务数据
        TestFlow _temp = new TestFlow();
        BeanUtils.copyProperties(dto, _temp);
        // 当前人
        Long userId = ThreadLocalUserUtil.get().getId();
        // 设置流程字段，flow_type请自行对应dict_flow_type表中的id
        FlowBusinessDataSuperEntity fbdse = WorkFlowUtil.getStartSuperDataEntity(userId,dto.getDepartmentId(),1,dto.getName());
        BeanUtils.copyProperties(fbdse, _temp);

        // 注意，此处由于FlowBusinessDataSuperEntity存在id=null，会覆盖操作对象，需要再设置id
        _temp.setId(dto.getId());
        // 插入业务表
        boolean flag = updateById(_temp);
        if(!flag) throw new CommonException("修改数据失败");
        // 重新开始流程
        int flowResult = new WorkFlowUtil<TestFlow,TestFlowMapper>(_temp.getId(),userId,TestFlow.class)
                .Begin(0L,"", temp);

        if(flowResult == 1){
            // 开始流程成功
            return true;
        }else{
            throw new CommonException("开始审核流程失败");
        }
    }

    @Override
    @Transactional
    public boolean check(TestFlowDTO dto){
        // 当前人
        Long userId = ThreadLocalUserUtil.get().getId();
        // 业务数据
        TestFlow tf = getById(dto.getId());
        TestFlow old_tf = new TestFlow();
        BeanUtils.copyProperties(tf,old_tf);
        // 当前审批轮次
        Long curCheckIndex = WorkFlowUtil.getCurCheckIndex(tf.getFlow_json(),dto.getNodeId());
        // 审核
        int flowResult = new WorkFlowUtil<TestFlow,TestFlowMapper>(dto.getId(),userId,TestFlow.class)
                .ToNext(new WorkFlowCheckDTO(dto.getNodeId(),curCheckIndex, JSONObject.toJSONString(old_tf)));
        if(flowResult == 1) {
            // 审核后仍然在流程中
            return true;
        }else if(flowResult == 2){
            // 审核后流程通过
            // todo 审核通过后的业务
            return true;
        }else{
            throw new CommonException("审核失败");
        }
    }
}
